package com.wg.net.client.websocket;

import com.wg.net.client.WgClient;
import com.wg.net.client.core.ClientConfig;
import com.wg.net.client.core.AbstractClient;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * WebSocket 协议客户端实现
 *
 * @author 少爷123
 */
public class WebSocketClient extends AbstractClient {
    public WebSocketClient(WgClient wgClient, ClientConfig config) {
        super(wgClient, config);
    }

    @Override
    protected ChannelFuture doSend(byte[] data) {
        ByteBuf buf = Unpooled.buffer();
        buf.writeInt(data.length);
        buf.writeBytes(data);
        return channel.writeAndFlush(new BinaryWebSocketFrame(buf));
    }

    @Override
    protected ChannelInitializer<? extends Channel> createInitializer() {
        WebSocketClientHandler handler = new WebSocketClientHandler(this, WebSocketClientHandshakerFactory
                .newHandshaker(config.getUri(), WebSocketVersion.V13, null, false, new DefaultHttpHeaders()));
        return new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) {
                ChannelPipeline p = ch.pipeline();
                p.addLast("logger", new LoggingHandler(LogLevel.DEBUG));
                p.addLast(new HttpClientCodec());
                p.addLast(new HttpObjectAggregator(8192));
                p.addLast(handler);
            }
        };
    }
}
